home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- title VxD2B.ASM - Example Device Driver #2b
- ;EM VxD2B - Example Device Driver #2b
- ;
- ; Copyright 1992, Cherry Hill Software
- ; All rights reserved.
- ;
- ; SUMMARY
- ; This driver simulates an interrupting device. The control
- ; port (output) has the following bit assignments:
- ;
- ; Bit 0 - Start I/O. Writing a zero to this bit begins
- ; I/O transfer. The "transfer" takes approximately
- ; one-tenth of a second. Writing a one to this
- ; bit has no effect.
- ;
- ; Bit 1 - Send EOI to device. Writing a zero to this bit
- ; sends End-of-Interrupt to the device and removes
- ; any pending interrupt request. Writing a one to
- ; this bit has no effect.
- ;
- ; All other bits: Always must write ones for future
- ; compatibility.
- ;
- ; When reading the port, the following is returned:
- ;
- ; Bit 0 - initially set, this is reset when output port bit
- ; 1 is reset and is set when the interrupt request
- ; is asserted. This bit is zero when the device
- ; is transferring data and is set to indicate
- ; transfer complete.
- ;
- ; Bit 1 - initially set, this is reset when the interrupt
- ; request is asserted and is reset when the device
- ; removes the interrupt request. This bit is zero
- ; to indicate a pending interrupt and is set if
- ; no interrupt is pending.
- ;
- ; All other bits: ignore returned value for future
- ; compatibility.
- ;
- ; WARNINGS
- ;
- ;
- .386p
-
-
- .xlist
- include vmm.inc
- include debug.inc
- include v86mmgr.inc
- include vpicd.inc
- include ..\include\bogus.inc
- .list
-
- VM_Not_Executable equ VM_Not_Executeable ; acckk!
-
- subttl VxD Declaration/Definition
- page
-
- VxD2B_Init_Order equ VNETBIOS_Init_Order+100 ; Do this after the Virtual net
- VxD2B_Device_ID equ Bogus_Device_ID
-
-
- Declare_Virtual_Device VXD2, 1, 0, VxD2B_Control, VxD2B_Device_ID, \
- VxD2B_Init_Order
-
-
- VxD_DATA_SEG
-
- ;
- ; Virtual Interrupt Descriptor Structure
- ;
- ; We pass this to VPIDC_Virtualize_IRQ. Here we specify the
- ; interrupt level, the hardware interrupt procedure, and the procedures
- ; that VPICD calls when the interrupt is dispatched into the VM and
- ; when the VM returns from the interrupt.
- ;
- IRQD VPICD_IRQ_Descriptor <FAKE_IRQ,,,OFFSET32 VxD2_VInt_Proc,\
- ,\
- OFFSET32 VxD2_Mask_Change_Proc,\
- OFFSET32 VxD2_IRET_Proc>
-
- hIRQ dd -1 ; IRQ handle
- hOwner dd -1 ; Owning VM handle
- hTimeout dd 0 ; handle to timeout callback (0=>none)
- bFakeData db 01111111b ; Fake I/O port data
-
- VxD_DATA_ENDS
-
-
-
- subttl Dispatch VxD Control
- page
- VxD_LOCKED_CODE_SEG
-
- BeginProc CheckOwner, NO_LOG
- cmp ebx,hOwner
- jne short co1
- ret ; exit if owner is calling
- co1:
- cmp hOwner,-1
- jne short co2 ; skip if non-owner calling
- mov hOwner,ebx ; set the owner
- ret
- co2:
- mov al,-1
- ret
- EndProc CheckOwner
-
-
- BeginProc TimeoutProc
- mov hTimeout,0 ; clear the handle
- cmp edx,hOwner ; Still the same owner?
- jne short to1 ; skip if not
- test bFakeData,FAKE_STAT_BUSY ; I/O pending?
- jnz short to1 ; skip if not
- cmp hOwner,-1 ; Do we have an owner?
- je short to1 ; skip if not
- mov eax,hIRQ
- mov ebx,hOwner
- VxDcall VPICD_Set_Int_Request ; assert the interrupt
- mov al,bFakeData
- and al,NOT (FAKE_STAT_IRQ) ; indicate so in status port
- or al,FAKE_STAT_BUSY ; indicate no longer busy
- mov bFakeData,al
- to1:
- ret
- EndProc TimeoutProc
-
-
- ;IP Port_IO_Callback - Process access to FAKE_PORT
- ;
- ; ENTRY
- ; EAX - The output value (for output instructions)
- ; EBX - The handle to the current VM
- ; ECX - The type of I/O operation
- ; DS,ES - FLAT
- ;
- ; EXIT
- ; EAX the input value (for input instructions)
- ;
- ; WARNINGS
- ;
- ; NOTES
- ; Note that we don't even look at the client register frame.
- ;
- ; We simply read and increment
- ;
- ; CALLS
- ;
- BeginProc Port_IO_Callback, NO_LOG
- Dispatch_Byte_IO Fall_Through,Port_Output_Callback
-
- Port_Input_Callback:
- call CheckOwner
- jc short ioexit
- mov al,bFakeData
- or bFakeData,FAKE_STAT_ERROR ; clear pending error
- ioexit:
- ret
-
- Port_Output_Callback:
- call CheckOwner
- jc short ioexit ; ignore I/O if not the owner
- test al,FAKE_CTL_START
- jnz short poc1 ; skip if not starting I/O
- test bFakeData,FAKE_STAT_BUSY
- jz short poc1 ; skip if already busy
- test bFakeData,FAKE_STAT_IRQ
- jz short poc1 ; skip if IRQ pending
- push eax
- push edx
- and bFakeData,NOT (FAKE_STAT_ERROR) ; presume error
- mov eax,100 ; callback in 1/10 second
- mov edx,hOwner ; pass the owner to the callback
- mov esi,OFFSET32 TimeoutProc
- VMMcall Set_VM_Time_Out
- pop edx
- pop eax
- or esi,esi
- jz short poc1 ; skip if error
- and bFakeData,NOT (FAKE_STAT_BUSY) ; indicate busy
- or bFakeData,FAKE_STAT_ERROR ; else, clear error indication
- mov hTimeout,esi ; save timeout handle
- poc1:
- test al,FAKE_CTL_EOI
- jnz short poc2 ; skip if not sending EOI
- test bFakeData,FAKE_STAT_IRQ ; interrupt pending?
- jnz short poc2 ; skip if not
- or bFakeData,FAKE_STAT_IRQ ; indicate interrupt no longer pending
- push eax
- mov eax,hIRQ
- VxDcall VPICD_Clear_Int_Request
- pop eax
- poc2:
- ret
- EndProc Port_IO_Callback
-
-
- ; ECX == 0 if unmasking (enabling), ECX != 0 if masking (disabling).
- BeginProc VxD2_Mask_Change_Proc
- call CheckOwner
- jc short mcp9 ; ignore if not the owner
- jcxz mcp9 ; skip if unmasking (enabling)
- ;
- ; The owner is relinquishing control. Allow another VM to sign up.
- ;
- mov hOwner,-1 ; clear the owner
-
- mcp9:
- ret
- EndProc VxD2_Mask_Change_Proc
-
-
- ; called when the ISR executes
- BeginProc VxD2_VInt_Proc
- mov eax,High_Pri_Device_Boost
- VMMCall Adjust_Exec_Priority ; boost priority for int processing
- ret
- EndProc VxD2_VInt_Proc
-
-
- ; called when the ISR returns (IRETs)
- BeginProc VxD2_IRET_Proc
- mov eax,-(High_Pri_Device_Boost)
- VMMCall Adjust_Exec_Priority ; restore priority
- ret
- EndProc VxD2_IRET_Proc
-
-
- ifdef DEBUG
- BeginProc VxD2B_Debug_Query
- Trace_Out "VxD2 has no debug command support."
- clc
- ret
- EndProc VxD2B_Debug_Query
- endif
-
-
- ;
- ; VxD2B_Control
- ;
-
- CtlDisp macro x
- Control_Dispatch x, VxD2B_&x
- endm
-
- Begin_Control_Dispatch VxD2B
- CtlDisp Device_Init
- ifdef DEBUG
- CtlDisp Debug_Query
- endif
- End_Control_Dispatch VxD2B
-
- VxD_LOCKED_CODE_ENDS
-
-
- VxD_CODE_SEG
- VxD_CODE_ENDS
-
-
- subttl Initialization Data
- page
- VxD_IDATA_SEG
- ; put initialization-only data here
- VxD_IDATA_ENDS
-
-
-
- subttl VxD Initialization
- page
- VxD_ICODE_SEG
-
- page
- ;EP VxD2B_Device_Init - Non-critical Device Initialization
- ;
- ; ENTRY
- ; EBP - Client frame
- ; EBX - System VM handle
- ; DS,ES - FLAT
- ;
- ; EXIT
- ; SUCCESS
- ; Carry clear
- ; FAILURE
- ; Carry set
- ;
- ; WARNINGS
- ;
- ; NOTES
- ;
- ; CALLS
- ;
-
- BeginProc VxD2B_Device_Init
- Debug_Out "VxD2B_Device_Init"
-
- mov edi,OFFSET32 IRQD
- VxDcall VPICD_Virtualize_IRQ ; Virtualize the interrupt
- jc short vdi1 ; exit if error
- mov hIRQ,eax ; save the handle
-
- mov edx,FAKE_PORT
- mov esi,OFFSET32 Port_IO_Callback
- VMMCall Install_IO_Handler
- VMMCall Enable_Global_Trapping ;
-
- clc ; No error
- vdi1:
- ret
- EndProc VxD2B_Device_Init
-
-
-
- VxD_ICODE_ENDS
-
-
- VxD_REAL_INIT_SEG
-
- VxD2B_Real_Init LABEL FAR ; Called before Windows enters protected mode
- mov ax,Device_Load_Ok ; Allow the VxD to load
- xor bx,bx ; No EMM Exclude pages
- xor si,si ; no instance data items
- ; pass edx unmodified
- ret
-
- VxD_REAL_INIT_ENDS
-
- END VxD2B_Real_Init
-